package com.diy.sigmund.diycommon.test.controller.other;

import com.diy.sigmund.diycommon.test.config.entity.ImportPerson;
import com.diy.sigmund.diycommon.util.json.JacksonUtil;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author ylm-sigmund
 * @since 2021/12/27 14:25
 */
@RestController
public class SerializableController {

    private static final Logger log = LoggerFactory.getLogger(SerializableController.class);

    @PostMapping("/serializableController/test")
    public ImportPerson test() {
        ImportPerson importPerson = new ImportPerson();
        importPerson.setName("xiaoMing");
        log.info("importPerson：{}", JacksonUtil.toJson(importPerson));
        return importPerson;
    }

    /**
     * JDK 自带的序列化具体的实现是由 ObjectOutputStream 完成的；而反序列化的具体实现是由 ObjectInputStream 完成的。
     * <br>将对象保存到文件，或者通过网络传输给对方，都是需要将对象转换二进制数据才能完成，那么对象转二进制数据的过程就是序列化，
     * <br>相反的，二进制数据转对象的过程就是反序列化的过程。
     * <br>
     * <br>我也给你介绍了几种常见的序列化方式：
     * <br>
     * <br>JDK 自带的序列化方式无法跨语言使用；
     * <br>
     * <br>JSON 序列化大多数语言都支持，JSON 优势是使用起来简单，容易阅读，应用广泛，缺点就是不适合大数据量的场景；
     * <br>
     * <br>ProtoBuf 使用需要定义 IDL 文件，序列化后体积相比 JSON 小很多，现在很多大公司都在用，gRPC 框架使用 protobuf 序列化。
     *
     * @see <a href="https://mp.weixin.qq.com/s/12sjb3WTKdQaDc0bvEX_ow">摊牌了，我是热心网友！</a>
     */
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        // String basePath = "/tmp";
        String basePath = "/";
        FileOutputStream fos = new FileOutputStream(basePath + "SerializableController.dat");

        //初始化一个学生对象
        ImportPerson student = new ImportPerson();
        student.setId(1);
        student.setName("xiaolin");

        //将学生对象序列化到文件里
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(student);
        oos.flush();
        oos.close();

        //读取文件中的二进制数据，并将数据反序列化为学生对象
        FileInputStream fis = new FileInputStream(basePath + "SerializableController.dat");
        ObjectInputStream ois = new ObjectInputStream(fis);
        ImportPerson deStudent = (ImportPerson) ois.readObject();
        ois.close();

        System.out.println(deStudent);
    }
}
